﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//using Plugin.TradeSharp.Helper;
//using Plugin.TradeSharp.Business;
using Tigera.Framework.Utility;
using Tigera.T_Definition;
using Tigera.LibCommon;
namespace Plugin.TradeSharp
{
    /// <summary>
    /// (个股)交易管理程序
    /// </summary>
    /// <remarks>
    /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
    /// 编写时间：<datetime>2012-10-16 5:10 PM</datetime>
    /// </remarks>
    public class TradeContext
    {
        #region Members.

        public static TradeContext Instance = new TradeContext();


        //ICurrentPriceProvider priceProvider = new DBFPriceProvider();

        //上海A股
        //买入时，1，佣金（按3‰计算，最低不少于5元）
        //2，过户费（按1‰计算，最低不少于1元）

        //卖出时，1，佣金（按3‰计算，最低不少于5元）
        //2，过户费（按1‰计算，最低不少于1元）
        //3，印花税（按1‰计算）


        //深圳A股
        //买入时，1，佣金（按3‰计算，最低不少于5元）

        //卖出时，1，佣金（按3‰计算，最低不少于5元）
        //2，印花税（按1‰计算）

        private const double 佣金比例 = 0.003;
        private const double 佣金最低 = 5.0;
        private const double 过户费比率 = 0.001;
        private const double 过户费最低 = 1.0;
        private const double 印花税比例 = 0.001;

        #endregion

        #region Ctor.

        private TradeContext()
        {

        }

        #endregion

        #region Properties

        /// <summary>
        /// 当日委托记录
        /// </summary>
        public EntrustList TodayEntrusts { get; set; }

        /// <summary>
        /// 当日成交记录
        /// </summary>
        
        public List<BusinessRecord> TodayBusiness 
        {
            
            get
            {
                return _todaybusiness;
            }
            set
            {
                _todaybusiness = value;
            }
        }
        List<BusinessRecord> _todaybusiness = new List<BusinessRecord> ();
        
        #endregion

        #region Public Methods.

        /// <summary>
        /// 买入交易
        /// 0.委托
        /// 1.获取当前价
        /// 2.计算花费
        /// 3.验证余额
        /// 4.委托确认
        /// 5.保存委托记录
        /// 6.记录日志
        /// </summary>
        /// <param name="stockCode">股票代码</param>
        /// <param name="amount">买入数量</param>
        /// <param name="priceType">价格类型</param>
        /// <returns>委托单号，-1为余额不足</returns>
        /// 
        /*
        public int EntrustOrder(string stockCode, int amount, Enums.PriceType priceType)
        {
            string stockAccount = GetStockAccount(stockCode);
            string exchangeType = GetExchangeType(stockCode);

            //0. check
            var chkResult = HSCOM.hS.F300委托股票(HsGateway.op_branch_no
                , AuthUserService.Instance.Password
                , HsGateway.branch_no
                , Convert.ToInt32(AuthUserService.Instance.FundAccount)
                , exchangeType
                , stockAccount
                , stockCode
                , "0");

            //1. get price
            double unitPrice = 0.0;
            try
            {
                unitPrice = priceProvider.GetPrice(stockCode, priceType);
            }
            catch (Exception e)
            {
                //Log.Exception("行情价格获取失败，请检查系统配置", e);
                return -1;
            }

            //2. calculate prices and other spent.
            double totalPrice = unitPrice * amount;
            totalPrice += (totalPrice * 佣金比例 > 佣金最低) ? totalPrice * 佣金比例 : 佣金最低;
            if (exchangeType == "1")
                totalPrice += (totalPrice * 过户费比率 > 过户费最低) ? totalPrice * 过户费比率 : 过户费最低;

            //3. validate
            if (totalPrice > chkResult.enable_balance)
            {
                return -1;
            }

            //4. buy
            var tradeResult = HSCOM.hS.F302委托确认(HsGateway.op_branch_no
                , AuthUserService.Instance.Password
                , HsGateway.branch_no
                , Convert.ToInt32(AuthUserService.Instance.FundAccount)
                , exchangeType
                , stockAccount
                , stockCode
                , amount
                , unitPrice
                , "0", ((int)(Enums.EntrustBs.买入)).ToString(), "0", "");

            //5. save 
            EntrustRecord entrust = new EntrustRecord();
            entrust.EntrustNo = tradeResult.entrust_no;
            entrust.StockCode = chkResult.stock_code;
            entrust.StockName = chkResult.stock_name;
            entrust.EntrustPrice = unitPrice;
            entrust.EntrustAmount = amount;
            entrust.Entrustbs = Enums.EntrustBs.买入;
            entrust.OpEntrustWay = Enums.OpEntrustWay.驻留委托;
            entrust.EntrustStatus = Enums.EntrustStatus.已报;
            entrust.TimeStamp = DateTime.Now;

            TodayEntrusts.Add(entrust);

            Log.Info(entrust.ToString());

            return tradeResult.entrust_no;
        }
        */
        /// <summary>
        /// 卖出交易（卖出数量验证需在外层做）
        /// 0.委托
        /// 1.获得行情价格
        /// 2.计算花费
        /// 3.验证余额
        /// 4.委托确认
        /// 5.保存委托记录
        /// 6.记录日志
        /// </summary>
        /// <param name="stockCode">股票代码</param>
        /// <param name="amount">卖出数量</param>
        /// <param name="priceType">价格类型</param>
        /// <returns>委托单号，-1为余额不足，-2为现有股数不足</returns>
        /*
        public int SellOrder(string stockCode, int amount, Enums.PriceType priceType)
        {
            string stockAccount = GetStockAccount(stockCode);
            string exchangeType = GetExchangeType(stockCode);

            //0. check
            var chkResult = HSCOM.hS.F300委托股票(HsGateway.op_branch_no
                , AuthUserService.Instance.Password
                , HsGateway.branch_no
                , Convert.ToInt32(AuthUserService.Instance.FundAccount)
                , exchangeType
                , stockAccount
                , stockCode
                , "0");

            //1. get price

            double unitPrice = 0.0;
            try
            {
                unitPrice = priceProvider.GetPrice(stockCode, priceType);
            }
            catch (Exception e)
            {
                //Log.Exception("行情价格获取失败，请检查系统配置", e);
                return -1;
            }

            //2. calculate other spent.
            double totalPrice = unitPrice * amount * (佣金比例 + 印花税比例);
            if (totalPrice < 7.0)
                totalPrice = 7.0;
            if (exchangeType == "1")
                totalPrice += (totalPrice * 过户费比率 > 过户费最低) ? totalPrice * 过户费比率 : 过户费最低;

            //3. validate
            if (totalPrice > chkResult.enable_balance)
            {
                return -1;
            }
            if (chkResult.enable_amount < amount)
            {
                return -2;
            }

            //4. sell
            var tradeResult = HSCOM.hS.F302委托确认(HsGateway.op_branch_no
                , AuthUserService.Instance.Password
                , HsGateway.branch_no
                , Convert.ToInt32(AuthUserService.Instance.FundAccount)
                , exchangeType
                , stockAccount
                , stockCode
                , amount
                , unitPrice
                , "0", "2", "0", "");

            //5. save 
            EntrustRecord entrust = new EntrustRecord();
            entrust.EntrustNo = tradeResult.entrust_no;
            entrust.StockCode = chkResult.stock_code;
            entrust.StockName = chkResult.stock_name;
            entrust.EntrustPrice = unitPrice;
            entrust.EntrustAmount = amount;
            entrust.Entrustbs = Enums.EntrustBs.卖出;
            entrust.OpEntrustWay = Enums.OpEntrustWay.驻留委托;
            entrust.EntrustStatus = Enums.EntrustStatus.已报;
            entrust.TimeStamp = DateTime.Now;

            TodayEntrusts.Add(entrust);

            Log.Info(entrust.ToString());

            return tradeResult.entrust_no;
        }
        */
        /// <summary>
        /// 调用接口更新当天委托
        /// （主动从接口获取所有委托，并更新至本地保存的文件中）
        /// </summary>
        /// 
        /*
        public void UpdateTodayEntrusts()
        {
            var newlocal = EntrustList.Load().Where(e => this.TodayEntrusts.Find(m => m.EntrustNo == e.EntrustNo) == null);
            if (newlocal.Count() > 0)
                this.TodayEntrusts.AddRange(newlocal.ToList());

            /*
            var result = HSCOM.hS.F451查询委托号码(HsGateway.op_branch_no, HsGateway.branch_no, Convert.ToInt32(AuthUserService.Instance.FundAccount), AuthUserService.Instance.Password, "", "", 0, "");
            foreach (var item in result)
            {
                var ent = this.TodayEntrusts.Find(e => e.EntrustNo == item.entrust_no);
                if (ent == null)
                {
                    EntrustRecord entrust = new EntrustRecord();
                    entrust.EntrustNo = item.entrust_no;
                    entrust.StockCode = item.stock_code;
                    entrust.StockName = item.stock_name;
                    entrust.EntrustPrice = item.entrust_price;
                    entrust.EntrustAmount = item.entrust_amount;
                    entrust.Entrustbs = (Enums.EntrustBs)Convert.ToInt32(item.entrust_bs);
                    entrust.OpEntrustWay = Enums.OpEntrustWay.驻留委托;
                    entrust.EntrustStatus = (Enums.EntrustStatus)Convert.ToInt32(item.entrust_status);
                    entrust.ReportTime = item.report_time;
                    entrust.BusinessAmount = item.business_amount;
                    entrust.TimeStamp = DateTime.Now;

                    TodayEntrusts.Add(entrust);
                }
                else
                {
                    ent.BusinessAmount = item.business_amount;
                    ent.EntrustStatus = (Enums.EntrustStatus)Convert.ToInt32(item.entrust_status);
                    ent.ReportTime = item.report_time;
                }
            }
        }
        */
        /// <summary>
        /// 调用接口更新当日成交（不保存，仅用于显示）
        /// </summary>
        /// 
        /*
        public void UpdateTodayBusiness()
        {


            if (AppMgr.MQMode)
            {
                //TODO
            }
            else
            {


                HSCOM.hS.OnList_ResultF402Evnet += new EventHandler<TiEventArgs<List<ResultF402>>>(hS_OnList_ResultF402);
                HSCOM.hS.F402查询成交(HsGateway.op_branch_no, HsGateway.branch_no, Convert.ToInt32(AuthUserService.Instance.FundAccount), AuthUserService.Instance.Password, "", "", "", "", "0", 4000, "");
                HSCOM.hS.OnList_ResultF402Evnet -= hS_OnList_ResultF402;
            }
            
        }
        */


        public void OnDealedOrders(object sender, TiEventArgs<List<TDealedOrder>> e)
        {

            AppMgr.Instance.Mqclient.OnList_ResultDealedOrder -= TradeContext.Instance.OnDealedOrders;

            var result = e.Data;

            TodayBusiness.Clear();
            foreach (var item in result)
            {
               
                    BusinessRecord business = new BusinessRecord();
                    business.BusinessAmount = item.business_amount;
                    business.BusinessBalance = item.business_balance;
                    business.BusinessPrice = item.business_price;
                    business.BusinessTime = item.business_time;
                    business.Entrustbs = item.entrust_bs;
                    business.OrderID = item.OrderID;
                    business.DealedID = item.DealedID;
                    business.StockAccount = item.Account;
                    business.StockCode = item.Code;
                    business.StockName = item.stock_name;

                    TodayBusiness.Add(business);
                
            }

            //StockPool.Instance.RefreshTodayExchangeSum();
            if (OnTodayDataRecieved != null)
            {
                OnTodayDataRecieved(this, EventArgs.Empty);
            }
        }
        public event EventHandler OnTodayDataRecieved;

        /// <summary>
        /// 从接口查询历史成交记录.
        /// </summary>
        /// <param name="dtstart">起始日期.</param>
        /// <param name="dtend">截止日期.</param>
        /// <returns>历史成交记录列表</returns>
        /// <remarks>
        /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
        /// 编写时间：<datetime>2012-10-16 5:29 PM</datetime>
        /// </remarks>
        /// 
        /*
        public List<BusinessRecord> UpdateHistoryBusiness(DateTime dtstart, DateTime dtend)
        {
            
            List<BusinessRecord> list = new List<BusinessRecord>();

            int start = Convert.ToInt32(dtstart.ToString("yyyyMMdd"));
            int end = Convert.ToInt32(dtend.ToString("yyyyMMdd"));

            var result = HSCOM.hS.F411查询历史成交(HsGateway.op_branch_no, HsGateway.branch_no, Convert.ToInt32(AuthUserService.Instance.FundAccount), AuthUserService.Instance.Password, start, end, "", "", "", "", 4000, "");

            foreach (var item in result)
            {
                BusinessRecord business = new BusinessRecord();
                business.BusinessAmount = item.occur_amount;
                business.BusinessBalance = item.business_balance;
                business.BusinessDate = item.date;
                business.BusinessPrice = item.business_price;
                business.BusinessTime = item.business_time;
                business.Entrustbs = (Enums.EntrustBs)Convert.ToInt32(item.entrust_bs);
                business.EntrustNo = item.entrust_no;
                business.SerialNo = item.serial_no;
                business.StockAccount = item.stock_account;
                business.StockCode = item.stock_code;
                business.StockName = item.stock_name;

                list.Add(business);
            }

            return list;
             */ 
        }

        /// <summary>
        /// 撤单操作
        /// </summary>
        /// <param name="entrustNo">合同编号</param>
        /// <param name="stockCode">股票代码</param>
        /// <returns>撤单合同编号或错代码</returns>
        /// 
    /*
        public int WithdrawOrder(int entrustNo, string stockCode)
        {
            string exchangeType = GetExchangeType(stockCode);

            var result = HSCOM.hS.F304委托撤单(HsGateway.op_branch_no
                , HsGateway.branch_no
                , int.Parse(AuthUserService.Instance.FundAccount)
                , AuthUserService.Instance.Password
                , "0"
                , exchangeType
                , entrustNo);

            return result.entrust_no;
          
            return 0;
        }
     * */

        #endregion

        #region Private Methods.

        /// <summary>
        /// 获得股票的交易类别.
        /// （上证1；深证2；创业板8）
        /// </summary>
        /// <param name="stockCode">股票代码.</param>
        /// <returns></returns>
        /// <remarks>
        /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
        /// 编写时间：<datetime>2012-10-16 5:18 PM</datetime>
        /// </remarks>
    /*    
    private string GetExchangeType(string stockCode)
        {
            if (int.Parse(stockCode) > 500000) //2012-11-7 添加，为了考虑ETF，虽不是正确的判断，但目前够用了)
                return "1";
            else if (stockCode.StartsWith("0"))
                return "2";
            else if (stockCode.StartsWith("3"))
                return "8";
            else
                return "0";
        }
    */
        /// <summary>
        /// 获得股票交易账号.
        /// </summary>
        /// <param name="stockCode">股票代码.</param>
        /// <returns></returns>
        /// <remarks>
        /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
        /// 编写时间：<datetime>2012-10-16 5:18 PM</datetime>
        /// </remarks>
    /*    
    private string GetStockAccount(string stockCode)
        {
            if (int.Parse(stockCode) > 500000) //2012-11-7 添加，为了考虑ETF，虽不是正确的判断，但目前够用了)
                return AuthUserService.Instance.SHStockAccount;
            else
                return AuthUserService.Instance.SZStockAccount;
        }
    
        
     *      * */
    #endregion
    }


